package sk.hackcraft.util.generator.empirical;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class DiscreteEmpiricalBuilder
{
	public static class ProbabiltyExceededException extends RuntimeException
	{
		public ProbabiltyExceededException(String message)
		{
			super("Probability exceeded: " + message);
		}
	}
	
	private double state;
	private final List<AbstractBuilderItem> optionList;
	
	public DiscreteEmpiricalBuilder()
	{
		this.optionList = new ArrayList<AbstractBuilderItem>();
		this.state = 0;
	}
	
	public void addOption(AbstractBuilderItem empiricalBuilderItem)
	{
		if(empiricalBuilderItem.getProbability() + this.state > 1)
		{
			throw new ProbabiltyExceededException("Option "+ empiricalBuilderItem.getProbability() +" is not possible to add!");
		}
		
		this.optionList.add(empiricalBuilderItem);
		this.state += empiricalBuilderItem.getProbability();
	}
	
	public boolean isValid()
	{
		return this.state == 1;
	}
	
	public List<AbstractBuilderItem> getItems()
	{
		return sortList(optionList);
	}
	
	/**
	 * Usporiadanie položiek buildera tak, aby položky s najväčšou
	 * pravdepodbnosťou boli umiestnené v strede a ku krajom položky
	 * s menšou pravdepodobnosťou
	 * @param list vstupný list položiek buildera
	 * @return výstupný list položiek buildera
	 */
	private List<AbstractBuilderItem> sortList(List<AbstractBuilderItem> list)
	{
		Collections.sort(list);
		
		AbstractBuilderItem[] newArray = new AbstractBuilderItem[list.size()];
		for(int i=0, si=0, ei=list.size()-1; i<list.size(); i+=2, si++, ei--)
		{
			newArray[si] = list.get(i);
			if(i+1 < list.size())
			{
				newArray[ei] = list.get(i+1);
			}
		}
		
		return Arrays.asList(newArray);
	}
}
